﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Diagnostics;
using System.Reflection;

namespace PickGold
{
	/// <summary>
	/// 纤程包装类
	/// </summary>
	public class Fiber : ICollection<FiberStart>
	{
		#region sealed class FiberTask

		abstract class FiberTask : IEnumerable, IEnumerator
		{
			public FiberTaskPool Pool;
			public MethodInfo Method;
			public DateTime Append;
			public DateTime Start;
			public DateTime Last;
			public DateTime Over;
			public long Watch;
			public long Sleep;

			public IEnumerator Enumerator;

			public Exception Error;

			public object Current
			{
				get
				{
					var e = this.GetEnumerator();
					if (e == null)
						return null;

					try
					{
						return e.Current;
					}
					catch (Exception x)
					{
						this.Enumerator = this;
						if (!this.OnError(x))
							throw;
					}
					return null;
				}
			}

			public bool MoveNext()
			{
				var e = this.GetEnumerator();
				if (e == null)
					return false;

				try
				{
					if (e.MoveNext())
						return true;
				}
				catch (Exception x)
				{
					if (!this.OnError(x))
						throw;
				}

				this.Enumerator = this;
				return false;
			}

			public void Reset()
			{
				try
				{
					var e = this.GetEnumerator();
					if (e != null)
						e.Reset();
				}
				catch (Exception x)
				{
					this.Enumerator = this;
					if (!this.OnError(x))
						throw;
				}
			}

			public IEnumerator GetEnumerator()
			{
				if (this.Enumerator == this)
					return null;

				if (this.Enumerator != null)
					return this.Enumerator;

				try
				{
					var e = this.Invoke();
					if (e == null)
						this.Enumerator = this;
					else
						this.Enumerator = e.GetEnumerator();
				}
				catch (Exception x)
				{
					this.Enumerator = this;
					if (!this.OnError(x))
						throw;
				}
				if (this.Enumerator == this)
					return null;

				return this.Enumerator;
			}

			public bool OnError(Exception error)
			{
				var p = this.Pool;
				var h = p == null ? null : p.GetErrorHandler();
				this.Error = error;
				if (h == null)
					return false;

				try
				{
					h(this.GetHandler(), new ThreadExceptionEventArgs(error));
					return true;
				}
				catch (Exception x)
				{
					error = x;
				}
				this.Error = error;
				return false;
			}

			internal protected abstract Delegate GetHandler();

			protected abstract IEnumerable Invoke();

			public static void UserWork(object data)
			{
				var b = false;
				var task = data as FiberTask;
				try
				{
					b = task.MoveNext();// ----------------------------------------------------------------------------- 执行
				}
				catch (ThreadAbortException x)
				{
					b = false;
					Tracker.WriteError(x);
				}
				task.Last = DateTime.Now;
				if (b)
				{
					var v = task.Current;
					if (v is FiberSleep)
					{
						task.Sleep = (int)((FiberSleep)v).Ticks;
						if (task.Sleep > task.Last.Ticks)
							task.Pool.Timer.Set(task);//执行未结束，重新队列
						else
							task.Pool.Set(task, int.MinValue, true);//执行未结束，重新队列
					}
					else
					{
						task.Pool.Set(task, int.MinValue, true);//执行未结束，重新队列
					}
					return;
				}

				task.Over = task.Last; //执行结束
			}
		}

		abstract class FiberTask<HANDLER, PARAMETER> : FiberTask where HANDLER : class
		{
			public HANDLER Handler;
			public PARAMETER Parameter;

			internal protected override Delegate GetHandler()
			{
				return this.Handler as Delegate;
			}
		}

		sealed class ActionTask : FiberTask<Action, object>
		{
			public ActionTask(FiberTaskPool pool, Action handler)
			{
				this.Pool = pool;
				this.Method = handler.Method;
				this.Handler = handler;
			}

			protected override IEnumerable Invoke()
			{
				this.Handler();
				return null;
			}
		}

		sealed class ActionWork<PARAMETER> : FiberTask<Action<PARAMETER>, PARAMETER>
		{
			public ActionWork(FiberTaskPool pool, Action<PARAMETER> handler, PARAMETER parameter)
			{
				this.Pool = pool;
				this.Method = handler.Method;
				this.Handler = handler;
				this.Parameter = parameter;
			}

			protected override IEnumerable Invoke()
			{
				this.Handler(this.Parameter);
				return null;
			}
		}

		sealed class ParameterizedWork<PARAMETER> : FiberTask<Func<PARAMETER, IEnumerable>, PARAMETER>
		{
			public ParameterizedWork(FiberTaskPool pool, Func<PARAMETER, IEnumerable> handler, PARAMETER parameter)
			{
				this.Pool = pool;
				this.Method = handler.Method;
				this.Handler = handler;
				this.Parameter = parameter;
			}

			protected override IEnumerable Invoke()
			{
				return this.Handler(this.Parameter);
			}
		}

		sealed class AsyncCallbackTask : FiberTask<AsyncCallback, IAsyncResult>
		{
			public AsyncCallbackTask(FiberTaskPool pool, AsyncCallback handler, IAsyncResult parameter)
			{
				this.Pool = pool;
				this.Method = handler.Method;
				this.Handler = handler;
				this.Parameter = parameter;
			}

			protected override IEnumerable Invoke()
			{
				this.Handler(this.Parameter);
				return null;
			}
		}

		sealed class WaitCallbackTask : FiberTask<WaitCallback, object>
		{
			public WaitCallbackTask(FiberTaskPool pool, WaitCallback handler, object parameter)
			{
				this.Pool = pool;
				this.Method = handler.Method;
				this.Handler = handler;
				this.Parameter = parameter;
			}

			protected override IEnumerable Invoke()
			{
				this.Handler(this.Parameter);
				return null;
			}
		}

		sealed class ParameterizedThreadStartTask : FiberTask<ParameterizedThreadStart, object>
		{
			public ParameterizedThreadStartTask(FiberTaskPool pool, ParameterizedThreadStart handler, object parameter)
			{
				this.Pool = pool;
				this.Method = handler.Method;
				this.Handler = handler;
				this.Parameter = parameter;
			}

			protected override IEnumerable Invoke()
			{
				this.Handler(this.Parameter);
				return null;
			}
		}

		sealed class ThreadStartTask : FiberTask<ThreadStart, object>
		{
			public ThreadStartTask(FiberTaskPool pool, ThreadStart handler, object parameter)
			{
				this.Pool = pool;
				this.Method = handler.Method;
				this.Handler = handler;
				this.Parameter = parameter;
			}

			protected override IEnumerable Invoke()
			{
				this.Handler();
				return null;
			}
		}

		sealed class FiberStartWork : FiberTask<FiberStart, object>
		{
			public FiberStartWork(FiberTaskPool pool, FiberStart handler, object parameter)
			{
				this.Pool = pool;
				this.Method = handler.Method;
				this.Handler = handler;
				this.Parameter = parameter;
			}

			protected override IEnumerable Invoke()
			{
				return this.Handler(this.Parameter);
			}
		}

		#endregion

		#region sealed class FiberTimer

		sealed class FiberTimer
		{
			public Thread Runner;
			public AutoResetEvent Waiter;
			public FiberTaskPool TaskPool;
			public List<FiberTask> TaskList;
			public DateTime LastActive;
			/// <summary>
			/// 需要休眠的时间刻度
			/// </summary>
			public long Sleep;
			/// <summary>
			/// 历史总数
			/// </summary>
			public long Tasks;
			/// <summary>
			/// 当前总数
			/// </summary>
			public int Count;

			public FiberTimer()
			{
				this.Waiter = new AutoResetEvent(false);
				this.TaskList = new List<FiberTask>();
			}

			public void Run()
			{
				int c;
				long d;
				FiberTask t;
				var rl = new List<FiberTask>();
				var tp = this.TaskPool;
				var ts = this.TaskList;
				var ew = this.Waiter;
				for (; ; )
				{
					tp = this.TaskPool;
					ew = this.Waiter;
					if (ew == null)
						return;

					this.LastActive = DateTime.Now;
					d = this.LastActive.Ticks;
					if (tp != null && tp.TimeoutKill > 0 && tp.EnterThreads > byte.MaxValue)
						tp.KillTimeout(tp.TimeoutKill);
					if (this.Sleep > d)
						ew.WaitOne(TimeSpan.FromTicks(this.Sleep - d));
					ts = this.TaskList;
					if (ts == null)
						return;

					this.LastActive = DateTime.Now;
					if (tp != null && this.LastActive - tp.LastActive > tp.BusyTimeout)//线程最后活动距当前已超过最大执行时间
					{
						if (tp.WaitingTasks > tp.MaxThreads * 2)
						{
							if (tp.WaitingTasks > 0)
								tp.Set(null, int.MaxValue, true);//创建线程，实际为通知使用系统线程池执行剩余任务
						}
						else
						{
							if (tp.WaitingTasks > tp.CurrentThreads &&//等待任务过多
								tp.CurrentThreads < tp.MaxThreads)//线程数未达上限
								tp.Set(null, int.MaxValue, true);//创建线程
							Tracker.WriteWarn("All threads have not been active for a long time.");
						}
					}
					if (!Monitor.TryEnter(ts, Fiber.LockTimeout))
						Fiber.ThrowLockTimeoutException(ts);
					try
					{
						c = ts.Count - this.Count;
						d = this.LastActive.Ticks;
						this.Sleep = d + TimeSpan.TicksPerMinute;//休眠最多不超过一分钟
						for (var i = ts.Count - 1; i >= 0; i--)
						{
							t = ts[i];
							if (t == null)
							{
								if (c > byte.MaxValue)
									ts.RemoveAt(i);
								continue;
							}

							if (d > t.Sleep)
							{
								this.Count--;
								ts[i] = null;
								rl.Add(t);
								continue;
							}

							if (this.Sleep > t.Sleep)
								this.Sleep = t.Sleep;
						}
					}
					finally
					{
						Monitor.Exit(ts);
					}
					c = rl.Count;
					if (c == 0)
						continue;

					if (c > byte.MaxValue)
						Tracker.WriteWarn("One time from timer to increase the tasks more than " + c);
					foreach (var ft in rl)
						this.TaskPool.Set(ft, int.MinValue, true);
					rl.Clear();
				}
			}

			public void Set(FiberTask task)
			{
				if (task == null && this.Runner != null)
					return;

				var ew = this.Waiter;
				var ts = this.TaskList;
				if (ew == null || ts == null)
					return;

				if (!Monitor.TryEnter(ts, Fiber.LockTimeout))
					Fiber.ThrowLockTimeoutException(ts);
				try
				{
					for (var i = ts.Count - 1; i >= 0; i--)
					{
						if (ts[i] == null)
						{
							this.Tasks++;
							this.Count++;
							ts[i] = task;
							ew.Set();
							return;
						}
					}

					this.Tasks++;
					this.Count++;
					ts.Add(task);
					ew.Set();
					if (this.Runner != null)
						return;

					this.Runner = new Thread(this.Run);
				}
				finally
				{
					Monitor.Exit(ts);
				}
				this.Runner.IsBackground = true;
				this.Runner.Priority = ThreadPriority.BelowNormal;
				this.Runner.Start();
			}
		}

		#endregion

		#region sealed class FiberThread

		sealed class FiberThread
		{
			/// <summary>
			/// 线程
			/// </summary>
			public Thread Runner;
			/// <summary>
			/// 当前任务
			/// </summary>
			public FiberTask Task;
			/// <summary>
			/// 线程方法
			/// </summary>
			public ParameterizedThreadStart Handler;
			/// <summary>
			/// 线程开始时间
			/// </summary>
			public DateTime Start;
			/// <summary>
			/// 最后执行结束时间
			/// </summary>
			public DateTime Last;
			/// <summary>
			/// 忙状态，如果 小于 <see cref="Last"/> 表示休眠等待中，否则表示正在忙，与当前时间差表示忙的时间，过长则表示可能不适合线程池来处理。
			/// </summary>
			public DateTime Busy;
			/// <summary>
			/// 总执行时间
			/// </summary>
			public long Watch;
			/// <summary>
			/// 调用次数
			/// </summary>
			public int Invokes;

			public FiberThread(ParameterizedThreadStart handler)
			{
				this.Handler = handler;
			}

			public FiberThread Go()
			{
				this.Start = DateTime.Now;
				this.Busy = this.Start;
				this.Last = this.Start;
				try
				{
					this.Runner = new Thread(this.Handler);
					this.Runner.IsBackground = true;
					this.Runner.Start(this);
				}
				catch (Exception x)
				{
					Tracker.LastError = x;
				}
				return this;
			}

			public static FiberThread Go(ParameterizedThreadStart handler)
			{
				var t = new FiberThread(handler);
				t.Start = DateTime.Now;
				t.Busy = t.Start;
				t.Last = t.Start;
				try
				{
					t.Runner = new Thread(t.Handler);
					t.Runner.IsBackground = true;
					t.Runner.Start(t);
				}
				catch (Exception x)
				{
					Tracker.LastError = x;
				}
				return t;
			}
		}

		#endregion

		#region sealed class FiberTaskPool

		class FiberTaskPool
		{
			private const int NEW_T = 1;
			/// <summary>
			/// 
			/// </summary>
			public static FiberTaskPool Value = new FiberTaskPool();

			public readonly ManualResetEvent Waiter = new ManualResetEvent(false);

			public readonly FiberTimer Timer = new FiberTimer();

			public readonly List<FiberThread> WaitList = new List<FiberThread>();

			public readonly List<FiberThread> ThreadList = new List<FiberThread>();

			public readonly Queue<FiberTask> TaskList = new Queue<FiberTask>();

			public readonly string[] TimeoutList = new string[byte.MaxValue];

			/// <summary>
			/// 最大线程数
			/// </summary>
			public int MaxThreads = BitUtil.K;//short.MaxValue;//byte.MaxValue;//

			/// <summary>
			/// 执行线程数，当前正在运行的
			/// </summary>
			public int EnterThreads = 0;
			/// <summary>
			/// 活动线程数，建议保持可执行的线程数，在有任务时，尽量只让此数目的线程来执行，如果执行不过来则使用其它更多线程执行。
			/// </summary>
			public int ActiveThreads = 0;
			/// <summary>
			/// 当前线程数，当前已创建的线程数，包括执行中的与休眠中的总和
			/// </summary>
			public int CurrentThreads = 0;
			/// <summary>
			/// 销毁线程数
			/// </summary>
			public int DestroyThreads = 0;
			/// <summary>
			/// 强制结束超时任务秒数
			/// </summary>
			public int TimeoutKill = 0;
			/// <summary>
			/// 历史超时任务
			/// </summary>
			private int TimeoutTasks = 0;
			/// <summary>
			/// 等待中的任务数
			/// </summary>
			public int WaitingTasks = 0;
			/// <summary>
			/// 历史总任务数
			/// </summary>
			public long HistoryTasks = 0;
			/// <summary>
			/// 溢出到系统线程池总任务数
			/// </summary>
			public long OverflowTasks = 0;
			/// <summary>
			/// 强制结束超时任务数
			/// </summary>
			private long TimeoutKills = 0;
			/// <summary>
			/// 最后线程活动时间
			/// </summary>
			public DateTime LastActive = DateTime.MinValue;
			/// <summary>
			/// 任务队列排队等待时间
			/// </summary>
			public TimeSpan QueueTimeout = TimeSpan.FromMinutes(1);
			/// <summary>
			/// 任务队列空闲等待时间
			/// </summary>
			public TimeSpan FreeTimeout = TimeSpan.FromMinutes(1);
			/// <summary>
			/// 任务队列繁忙等待时间
			/// </summary>
			public TimeSpan BusyTimeout = TimeSpan.FromSeconds(1);
			/// <summary>
			/// 任务计数器
			/// </summary>
			public Dictionary<string, int> TaskCounter;

			public event ThreadExceptionEventHandler Error;

			public ThreadExceptionEventHandler GetErrorHandler()
			{
				return this.Error;
			}

			/// <summary>
			/// 
			/// </summary>
			/// <param name="x"></param>
			/// <param name="y"></param>
			/// <returns>一个有符号整数，它指示 <paramref name="x"/> 与 <paramref name="y"/> 的相对值，如下表所示。值含义小于 0x 小于 <paramref name="y"/>。0x 等于 <paramref name="y"/>。大于 0x 大于 <paramref name="y"/>。</returns>
			private int Comparison(FiberTask x, FiberTask y)
			{
				if (x == null && y == null)
					return 0;

				if (x == null)
					return int.MinValue;

				if (y == null)
					return int.MaxValue;

				var xa = x.Append.Ticks;
				var ya = y.Append.Ticks;
				if (x.Last > DateTime.MinValue)
					xa = x.Last.Ticks;
				if (y.Last > DateTime.MinValue)
					ya = y.Last.Ticks;
				return (int)(xa - ya);//(ya - xa);//
			}

			private void Run(FiberTask task, Dictionary<string, int> counter, DateTime current, TimeSpan runtime)
			{
				if (task == null)
					return;

				var m = task.Method;
				if (m == null)
					return;

				var i = 0;
				var t = m.DeclaringType.Name + "." + m.Name;
				if (counter == null)
				{
					this.TimeoutList[this.TimeoutTasks++ % this.TimeoutList.Length] = current + "(" + runtime + ")" + t;
					Tracker.WriteWarn("执行时间过长（" + runtime.TotalSeconds + "s）的线程方法：" + t);
					return;
				}

				counter.TryGetValue(t, out i);
				counter[t] = i + 1;
			}
			/// <summary>
			/// 线程主体
			/// </summary>
			/// <param name="ft"></param>
			private void Run(FiberThread ft)
			{
				var b = false;
				var d = DateTime.MinValue;
				var v = Reflector.Null;
				var ew = this.Waiter;
				var ts = this.TaskList;
				var tc = this.TaskCounter;
				for (; ; )
				{
					Thread.Sleep(1);//Thread.Yield();
					d = DateTime.Now;
					this.LastActive = d;
					ew = this.Waiter;
					if (this.LastActive - ft.Last > this.FreeTimeout || !ew.WaitOne(this.FreeTimeout))//ft.Last 已在构造时初始化
						break;

					tc = this.TaskCounter;
					ts = this.TaskList;
					ew = this.Waiter;
					if (ts == null || ew == null)
						break;

					v = null;//非强制删除
					this.Run(ft, this.WaitingTasks, ref v);//非强制删除表示判断等待列表最后一个是否为当前线程
					if (v == null)//等待列表最后一个不是当前线程，则放弃执行
						continue;

					if (!Monitor.TryEnter(ts, Fiber.LockTimeout))
						Fiber.ThrowLockTimeoutException(ts);
					try
					{
						this.WaitingTasks = ts.Count;
						if (this.WaitingTasks == 0)
						{
							this.Run(ft, int.MinValue, ref v);
							ew.Reset();
							continue;
						}

						if (this.WaitingTasks == 1)
							ew.Reset();//没有操作，通知线程下次应休眠
						ft.Task = ts.Dequeue();// ts[0];//ts.RemoveAt(0);
						if (tc != null && ft.Task != null)
							this.Run(ft.Task, tc, DateTime.MinValue, TimeSpan.Zero);
					}
					finally
					{
						Monitor.Exit(ts);
					}
					if (ft.Task == null)
					{
						this.Run(ft, int.MinValue, ref v);
						continue;
					}

					Interlocked.Increment(ref this.EnterThreads);
					d = DateTime.Now;
					if (d - this.LastActive > Fiber.Slow)
					{
						if (this.ActiveThreads < this.MaxThreads)
							this.ActiveThreads++;
					}
					else
					{
						if (this.ActiveThreads > 0)
							this.ActiveThreads--;
					}
					this.LastActive = d;
					ft.Invokes++;
					ft.Busy = this.LastActive;
					if (ft.Task.Start == DateTime.MinValue)
						ft.Task.Start = ft.Busy;
					ft.Task.Last = ft.Busy;
					try
					{
						b = ft.Task.MoveNext();// ----------------------------------------------------------------------------- 执行
					}
					catch (ThreadAbortException x)
					{
						b = false;
						Tracker.WriteError(x);
					}
					this.LastActive = DateTime.Now;
					ft.Last = this.LastActive;
					ft.Watch = ft.Watch + ft.Last.Ticks - ft.Busy.Ticks;
					ft.Task.Watch = ft.Task.Watch + ft.Last.Ticks - ft.Busy.Ticks;
					ft.Task.Last = ft.Last;
					Interlocked.Decrement(ref this.EnterThreads);
					if (b)
					{
						v = ft.Task.Current;
						if (v is FiberSleep)
						{
							ft.Task.Sleep = (int)((FiberSleep)v).Ticks;
							if (ft.Task.Sleep > ft.Last.Ticks)
								this.Timer.Set(ft.Task);//执行未结束，重新队列
							else
								this.Set(ft.Task, int.MinValue, true);//执行未结束，重新队列
						}
						else
						{
							this.Set(ft.Task, int.MinValue, true);//执行未结束，重新队列
						}
						v = ft;
					}
					else
					{
						ft.Task.Over = ft.Last; //执行结束
					}
					if (ft.Last - ft.Busy >= Fiber.LockTimeout)
						this.Run(ft.Task, null, ft.Last, ft.Last - ft.Busy);
					this.Run(ft, int.MinValue, ref v);
				}
			}
			/// <summary>
			/// 添加删除线程管理列表
			/// </summary>
			/// <param name="ft"></param>
			/// <param name="remove"></param>
			private void Run(FiberThread ft, bool remove)
			{
				var ts = this.ThreadList;
				if (ts == null)
					return;

				if (!Monitor.TryEnter(ts, Fiber.LockTimeout))
					Fiber.ThrowLockTimeoutException(ts);
				try
				{
					if (remove)
						ts.Remove(ft);
					else
						ts.Add(ft);
				}
				finally
				{
					Monitor.Exit(ts);
				}
			}
			/// <summary>
			/// 添加删除线程等待列表
			/// </summary>
			/// <param name="ft"></param>
			/// <param name="remove">大于等于零为删除</param>
			/// <param name="force">非空表示强制删除，否则表示如果等待列表最后一个为当前线程则删除成功，操作成功返回为非空</param>
			private void Run(FiberThread ft, int remove, ref object force)
			{
				var ts = this.WaitList;
				if (ts == null)
					return;

				if (!Monitor.TryEnter(ts, Fiber.LockTimeout))
					Fiber.ThrowLockTimeoutException(ts);
				try
				{
					if (remove < 0)//添加
					{
						if (force != null)
							ts.Add(ft);
						return;
					}

					if (force != null)
					{
						force = ft;
						ts.Remove(ft);
						return;
					}

					var c = ts.Count;//等待（休眠）的线程数
					if (--c < 0)
					{
						force = ft;
						return;
					}

					if (remove + 2 >= c && this.ActiveThreads > c)//如果等待数量大于等待线程总数，直接成功
					{
						force = ft;
						ts.Remove(ft);
						return;
					}

					if (ts[c] == ft || this.WaitingTasks > this.MaxThreads)//最后一个进入排队的为当前线程 *或* 等待数量过多
					{
						force = ts[c];
						ts.RemoveAt(c);//最后一个进入排队的为当前线程，则删除成功
						return;
					}

					if (remove > this.ActiveThreads)
					{
						if (this.ActiveThreads <= 0)
							return;

						remove = this.ActiveThreads;
					}
					remove = c - remove;
					for (; c >= remove; c--)
					{
						if (ts[c] == ft)
						{
							force = ts[c];
							ts.RemoveAt(c);//最后一个进入排队的为当前线程，则删除成功
							return;
						}
					}
				}
				finally
				{
					Monitor.Exit(ts);
				}
			}
			/// <summary>
			/// 线程入口
			/// </summary>
			/// <param name="data"></param>
			private void Run(object data)
			{
				var ft = data as FiberThread;
				this.Timer.TaskPool = this;
				Interlocked.Increment(ref this.CurrentThreads);
				this.Run(ft, false);
				this.Run(ft, int.MinValue, ref data);
				try
				{
					this.Run(ft);
				}
				catch (ThreadAbortException x)
				{
					Tracker.WriteError(x);//强制中断
				}
				finally
				{
					this.Run(ft, int.MaxValue, ref data);
					this.Run(ft, true);
					Interlocked.Decrement(ref this.CurrentThreads);
					Interlocked.Increment(ref this.DestroyThreads);
				}
			}

			/// <summary>
			/// 
			/// </summary>
			/// <param name="task">空将尝试创建主线程。</param>
			/// <param name="sleep">大于零将进入等待队列，等于最小整数将不允许进入系统线程池。</param>
			/// <param name="force"> 不管线程池是否已满，强制进入队列。</param>
			/// <returns></returns>
			public bool Set(FiberTask task, int sleep, bool force)
			{
				var ts = this.TaskList;
				var now = DateTime.Now;
				if (task == null)
				{
					if (this.WaitingTasks > this.CurrentThreads * NEW_T &&
						this.CurrentThreads < this.MaxThreads &&
						this.BusyTimeout.Ticks < sleep)
					{
						FiberThread.Go(this.Run);
						return false;
					}

					if (this.WaitingTasks > 0 && this.WaitingTasks > this.MaxThreads * 2)
					{
						Tracker.WriteWarn("Fiber Thread Pool: Reduce, Max: {0}, Tasks = {1}", this.MaxThreads, this.WaitingTasks);
						if (!Monitor.TryEnter(ts, Fiber.LockTimeout))
							Fiber.ThrowLockTimeoutException(ts);
						try
						{
							this.WaitingTasks = sleep = ts.Count;
							if (sleep == 0)
								return false;

							task = ts.Dequeue();// ts[0];//ts.RemoveAt(0);
							if (ThreadPool.QueueUserWorkItem(FiberTask.UserWork, task))
							{
								this.WaitingTasks = ts.Count;
								Interlocked.Increment(ref this.OverflowTasks);
								return true;
							}

							ts.Enqueue(task);
						}
						catch
						{
							if (task != null)
								ts.Enqueue(task);
						}
						finally
						{
							Monitor.Exit(ts);
						}
					}
					return false;
				}

				var tm = this.Timer;
				if (tm == null)
					return false;

				if (task.Append == DateTime.MinValue)
					task.Append = now;
				if (sleep > 0)
				{
					task.Sleep = now.AddMilliseconds(sleep).Ticks;
					tm.TaskPool = this;
					tm.Set(task);
					return true;
				}

				if (this.MaxThreads <= 0 && !force)
					return false;

				if (this.WaitingTasks > this.MaxThreads * 2)
				{
					if (sleep > int.MinValue)
					{
						Tracker.WriteWarn("Fiber Thread Pool: Overflow, Active = {0}, Current = {1}, Tasks: {2}", this.EnterThreads, this.CurrentThreads, this.WaitingTasks);
						if (Thread.CurrentThread.IsThreadPoolThread && !force)
							return false;

						try
						{
							if (ThreadPool.QueueUserWorkItem(FiberTask.UserWork, task))
							{
								Interlocked.Increment(ref this.OverflowTasks);
								return true;
							}
						}
						catch (Exception x)
						{
							if (force)
								throw;

							Tracker.WriteError(x);
						}
						return false;
					}

					task.Sleep = now.AddMilliseconds(1000).Ticks;
					tm.TaskPool = this;
					tm.Set(task);
					return true;
				}

				var ew = this.Waiter;
				if (ts == null || ew == null)
					return false;

				if (!Monitor.TryEnter(ts, Fiber.LockTimeout))
					Fiber.ThrowLockTimeoutException(ts);
				try
				{
					this.WaitingTasks = ts.Count + 1;
					this.HistoryTasks++;
					ts.Enqueue(task);//ts.Sort(this.Comparison);
				}
				finally
				{
					Monitor.Exit(ts);
				}
				ew.Set();
				if (this.WaitingTasks > this.CurrentThreads * NEW_T)//等待任务过多，超过线程一定的倍数
				{
					var ls = now - this.LastActive;
					if (ls > Fiber.Slow)//整体线程池执行速度慢，执行时间超过 255 毫秒
					{
						if (this.CurrentThreads < this.MaxThreads / 2)//线程数未达上限的一半
							FiberThread.Go(this.Run);//直接创建
						else if (this.CurrentThreads < this.MaxThreads && ls > this.BusyTimeout)//线程数未达上限且线程池执行时间过慢，超过执行超时时间上限
							FiberThread.Go(this.Run);//直接创建
						else if (tm.Tasks == 0)//由计时器判断创建线程：等待任务超过线程数，且线程数未达上限，且执行时间超过执行超时时间上限
							tm.Set(null);// this.Set(null, int.MaxValue);
					}
				}
				if (this.WaitingTasks > this.MaxThreads)
					Tracker.WriteWarn("Fiber Thread Pool: More, Active = {0}, Current = {1}, Tasks: {2}", this.EnterThreads, this.CurrentThreads, this.WaitingTasks);
				return true;
			}

			/// <summary>
			/// 杀死超时任务。
			/// </summary>
			/// <param name="timeout">超时秒数。</param>
			/// <returns>杀死任务数。</returns>
			public int KillTimeout(int timeout)
			{
				var ts = this.ThreadList;
				if (ts == null || timeout <= 0 || !Monitor.TryEnter(ts, Fiber.LockTimeout))
					return 0;

				var v = 0;
				var d = DateTime.Now.Ticks;
				var k = TimeSpan.TicksPerSecond * timeout;
				try
				{
					for (var i = ts.Count - 1; i >= 0; i--)
					{
						var t = ts[i];
						if (t == null)
							continue;

						if (t.Busy > t.Last && d - t.Busy.Ticks >= k)
						{
							try
							{
								t.Runner.Abort();
								this.TimeoutKills++;
								v++;
							}
							catch (Exception x)
							{
								Tracker.WriteError(x);
							}
						}
					}
				}
				finally
				{
					Monitor.Exit(ts);
				}
				return v;
			}

			/// <summary>
			/// 仅供 <see cref="Tracker"/> 调用
			/// </summary>
			/// <returns>跟踪状态</returns>
			public string GetPoolTrace(string command)
			{
				var w = 0;
				var c = 0;
				var o = string.Empty;
				var v = string.Empty;
				var d = DateTime.Now;
				var p = Process.GetCurrentProcess();
				var rs = this.ThreadList;
				var ts = this.TaskList;
				var tm = this.Timer;
				var ms = tm == null ? null : tm.TaskList;
				if (rs == null || ts == null)
				{
					v = "Pool disposed!";
					return v;
				}

				#region x = kill or scheduled
				c = command.IndexOf(" x a", StringComparison.OrdinalIgnoreCase);
				if (c >= 0)
				{
					w = command.LastIndexOf(' ');
					if (w > c && int.TryParse(command.Substring(w + 1), out w) && w > 0)
						c = this.KillTimeout(w);
					else
						c = 0;
					v = v + "Kill tasks: " + c + "/" + this.TimeoutKills + Environment.NewLine;
					return v;
				}

				c = command.IndexOf(" x s", StringComparison.OrdinalIgnoreCase);
				if (c >= 0)
				{
					w = command.LastIndexOf(' ');
					if (w > c && int.TryParse(command.Substring(w + 1), out w))
						this.TimeoutKill = w;
					v = v + "Kill scheduled at " + this.TimeoutKill + " seconds, Kill tasks: " + this.TimeoutKills + Environment.NewLine;
					return v;
				}
				#endregion

				#region m = max thread
				c = command.IndexOf(" m", StringComparison.OrdinalIgnoreCase);
				if (c >= 0)
				{
					v = v + "Fiber Pool Max: " + this.MaxThreads + Environment.NewLine;
					w = command.LastIndexOf(' ');
					if (w > c && int.TryParse(command.Substring(w + 1), out w) && w != 0 && w < short.MaxValue)
						this.MaxThreads = w;
					v = v + "Fiber Pool Max: " + this.MaxThreads + Environment.NewLine;
					return v;
				}
				#endregion

				#region c = counter
				c = command.IndexOf(" c", StringComparison.OrdinalIgnoreCase);
				if (c >= 0)
				{
					w = command.IndexOf(" cc", StringComparison.OrdinalIgnoreCase);
					if (w == c)
					{
						if (this.TaskCounter == null)
							this.TaskCounter = new Dictionary<string, int>();
						else
							this.TaskCounter = null;
						v = "Counter ";
						if (this.TaskCounter == null)
							return v + "OFF" + Environment.NewLine;

						return v + "ON" + Environment.NewLine;
					}

					var tc = this.TaskCounter;
					if (tc == null)
					{
						v = v + "Tasks: Current=" + this.WaitingTasks + "; Hsitory=" + this.HistoryTasks + "; Timeout=" + this.TimeoutTasks + Environment.NewLine;
						v = v + "Fiber Pool: Active=" + this.EnterThreads + "; Capacity=" + this.CurrentThreads + "; Destroy=" + this.DestroyThreads + Environment.NewLine;
						return v + "Please input ( cc) to trun on the counter." + Environment.NewLine;
					}

					if (!Monitor.TryEnter(ts, Fiber.LockTimeout))
					{
						v = "Lock Threads timeout, try later.";
						return v;
					}

					try
					{
						w = c = 0;
						foreach (var item in tc)
						{
							if (++c > byte.MaxValue)
								v = v + item.Value.ToString().PadLeft(8, ' ') + "    " + item.Key + Environment.NewLine;
						}
					}
					finally
					{
						Monitor.Exit(ts);
					}
					return v + "Please input ( cc) to trun off the counter." + Environment.NewLine;
				}
				#endregion

				#region t = timeout
				c = command.IndexOf(" t", StringComparison.OrdinalIgnoreCase);
				if (c >= 0)
				{
					v = "Timeout task list:" + Environment.NewLine;
					for (var i = this.TimeoutList.Length - 1; i >= 0; i--)
					{
						if (this.TimeoutList[i] != null)
							v = v + this.TimeoutList[i] + Environment.NewLine;
					}
					v = v + "Tasks: Current=" + this.WaitingTasks + "; Hsitory=" + this.HistoryTasks + "; Timeout=" + this.TimeoutTasks + Environment.NewLine;
					v = v + "Fiber Pool: Active=" + this.EnterThreads + "; Capacity=" + this.CurrentThreads + "; Destroy=" + this.DestroyThreads + Environment.NewLine;
					return v;
				}
				#endregion

				#region b(busy) or x(kill)
				c = command.IndexOf(" b", StringComparison.OrdinalIgnoreCase);
				if (c >= 0)
				{
					o = AsciiString.B;
				}
				else
				{
					c = command.IndexOf(" x", StringComparison.OrdinalIgnoreCase);
					if (c >= 0)
					{
						w = command.IndexOf(" x ", StringComparison.OrdinalIgnoreCase);
						if (c == w)
							o = AsciiString.X;
						else
							o = AsciiString.B;
						v = v + "Input ( x a <second>) only once to kill all timeout task." + Environment.NewLine;
						v = v + "Input ( x s <second>) scheduled to kill all timeout task." + Environment.NewLine;
					}
					else
					{
						o = null;
					}
				}
				if (o == AsciiString.B)
					v = v + "List busy task only, input ( x <id>) to kill task." + Environment.NewLine;
				#endregion
				if (!Monitor.TryEnter(rs, Fiber.LockTimeout))
				{
					v = "Lock Threads timeout, try later.";
					return v;
				}

				try
				{
					v = v + "Id    Start     Watch(s)  Invokes State(s)    Task" + Environment.NewLine;
					c = rs.Count;
					for (var i = c - 1; i >= 0; i--)
					{
						var t = rs[i];
						if (t == null)
						{
							c--;
							continue;
						}

						if (o == AsciiString.B && t.Last >= t.Busy)
							continue;

						if (o == AsciiString.X && command.EndsWith(" " + t.Runner.ManagedThreadId))
						{
							v = v + "Kill " + t.Runner.ManagedThreadId + Environment.NewLine;
							try
							{
								t.Runner.Abort(this);
								this.TimeoutKills++;
							}
							catch (Exception x)
							{
								v = v + "Kill Error: " + x.Message + Environment.NewLine;
							}
							continue;
						}

						if (w > byte.MaxValue)
						{
							if (o == AsciiString.X)
								continue;

							break;
						}

						var k = t.Task;
						var m = k == null ? null : k.Method;
						v = v +
							t.Runner.ManagedThreadId.ToString().PadRight(6, ' ') +
							t.Start.ToString("dd HH:mm") + "  " +
							TimeSpan.FromTicks(t.Watch).TotalSeconds.ToString("#0.00").PadLeft(8, ' ') + "  " +
							t.Invokes.ToString().PadRight(6, ' ') + "  " +
							(t.Busy > t.Last ? "Busy:" + (d - t.Busy).TotalSeconds.ToString("#0.00") : "Wait:" + (d - t.Last).TotalSeconds.ToString("#0.00")).PadRight(12, ' ') +
							//(t.Handler == null || t.Handler.Method == null ? string.Empty : t.Handler.Method.DeclaringType.Name + ":" + t.Handler.Method.Name) + "    " +
							(m == null ? string.Empty : m.DeclaringType.Name + ":" + m.Name) + "    " +
							Environment.NewLine;
						w++;
					}
					if (c > w)
						v = v + "The remaining " + (c - w) + " items not shown ..." + Environment.NewLine;
				}
				finally
				{
					Monitor.Exit(rs);
				}
				v = v + "Fiber Pool Max: " + this.MaxThreads + "; Kill: " + this.TimeoutKills + "; Scheduled(s): " + this.TimeoutKill + Environment.NewLine;
				v = v + "Tasks: Current=" + this.WaitingTasks + "; Hsitory=" + this.HistoryTasks + "; Timeout=" + this.TimeoutTasks + "; Overflow=" + this.OverflowTasks + Environment.NewLine;
				if (ms != null)
				{
					if (!Monitor.TryEnter(ms, Fiber.LockTimeout))
					{
						v = v + "Lock Timers timeout, try later." + Environment.NewLine;
					}
					else
					{
						try
						{
							w = c = ms.Count;
							for (var i = 0; i < c; i++)
							{
								if (ms[i] == null)
									w--;
							}
							v = v + "Timers: Current=" + w + "; Capacity=" + c + "; Hsitory=" + tm.Tasks + "; Last=" + tm.LastActive + Environment.NewLine;
						}
						finally
						{
							Monitor.Exit(ms);
						}
					}
				}
				v = v + "Fiber Pool: Active=" + this.EnterThreads + "; Capacity=" + this.CurrentThreads + "; Destroy=" + this.DestroyThreads + "; Last=" + this.LastActive + Environment.NewLine;
				ThreadPool.GetMinThreads(out w, out c);
				v = v + "System Pool Min: Worker=" + w + "; Completion=" + c + Environment.NewLine;
				ThreadPool.GetAvailableThreads(out w, out c);
				v = v + "System Pool Available: Worker=" + w + "; Completion=" + c + Environment.NewLine;
				ThreadPool.GetMaxThreads(out w, out c);
				v = v + "System Pool Max: Worker=" + w + "; Completion=" + c + Environment.NewLine;
				v = v + "Process Threads: " + p.Threads.Count + Environment.NewLine;
				v = v + "Process Modules: " + p.Modules.Count + Environment.NewLine;
				return v;
			}
		}

		#endregion

		/// <summary>
		/// 运行时间慢于此时间的为代码
		/// </summary>
		public static TimeSpan Slow = TimeSpan.FromMilliseconds(byte.MaxValue);

		/// <summary>
		/// 锁超时的时间，默认为一分钟。
		/// </summary>
		public static TimeSpan LockTimeout = TimeSpan.FromMinutes(1);

		private Dictionary<FiberStart, FiberTask> _Tasks;
		private FiberStart _Current;

		/// <summary>
		/// 构造一个纤程对象
		/// </summary>
		public Fiber()
		{
			this._Tasks = new Dictionary<FiberStart, FiberTask>();
		}

		/// <summary>
		/// 构造一个纤程对象
		/// </summary>
		/// <param name="capacity">初始元素数</param>
		public Fiber(int capacity)
		{
			this._Tasks = new Dictionary<FiberStart, FiberTask>(capacity);
		}

		/// <summary>
		/// 转移纤程
		/// </summary>
		public void Yield()
		{
			foreach (var item in this._Tasks)
			{
				try
				{
					if (this._Current != null)
					{
						if (this._Current == item.Key)
							this._Current = null;
						continue;
					}

					if (!item.Value.MoveNext())
					{
						this._Current = item.Key;
						this.Yield();
						this._Tasks.Remove(item.Key);
						break;
					}
				}
				catch
				{
					this._Current = item.Key;
					this.Yield();
					this._Tasks.Remove(item.Key);
					throw;
				}
			}
			this._Current = null;
		}

		/// <summary>
		/// 添加纤程任务
		/// </summary>
		/// <param name="argument">参数</param>
		/// <param name="item">纤程任务：【yield return ?】【yield break】</param>
		public void Yield(FiberStart item, object argument)
		{
			if (item != null)
				this._Tasks[item] = new FiberStartWork(FiberTaskPool.Value, item, argument);
			else
				this.Yield();
		}

		void ICollection<FiberStart>.Add(FiberStart item)
		{
			this.Yield(item, null);
		}

		void ICollection<FiberStart>.Clear()
		{
			this._Tasks.Clear();
		}

		/// <summary>
		/// 是否存在指定任务
		/// </summary>
		/// <param name="item">指定的任务</param>
		/// <returns>是否存在</returns>
		public bool Contains(FiberStart item)
		{
			return this._Tasks.ContainsKey(item);
		}

		void ICollection<FiberStart>.CopyTo(FiberStart[] array, int arrayIndex)
		{
			this._Tasks.Keys.CopyTo(array, arrayIndex);
		}

		/// <summary>
		/// 当前任务总数
		/// </summary>
		public int Count
		{
			get
			{
				return this._Tasks.Count;
			}
		}

		bool ICollection<FiberStart>.IsReadOnly
		{
			get
			{
				return false;
			}
		}

		bool ICollection<FiberStart>.Remove(FiberStart item)
		{
			return this._Tasks.Remove(item);
		}

		/// <summary>
		/// 取枚举器
		/// </summary>
		/// <returns>枚举器</returns>
		public IEnumerator<FiberStart> GetEnumerator()
		{
			return this._Tasks.Keys.GetEnumerator();
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return this.GetEnumerator();
		}

		#region QueueThreadTask

		/// <summary>
		/// 任务线程错误。
		/// </summary>
		public static event ThreadExceptionEventHandler UserWorkError
		{
			add
			{
				FiberTaskPool.Value.Error += value;
			}
			remove
			{
				FiberTaskPool.Value.Error -= value;
			}
		}

		/// <summary>
		/// 添加后台任务
		/// </summary>
		/// <param name="task">后台任务</param>
		/// <param name="sleep">休眠毫秒数</param>
		/// <param name="force">强制进入线程池，否则抛出异常</param>
		/// <returns>是否成功添加</returns>
		public static bool QueueUserWorkItem(Action task, int sleep = 0, bool force = false)
		{
			return FiberTaskPool.Value.Set(new ActionTask(FiberTaskPool.Value, task), sleep, force);
		}
		/// <summary>
		/// 添加后台任务
		/// </summary>
		/// <param name="task">后台任务</param>
		/// <param name="sleep">休眠毫秒数</param>
		/// <param name="force">强制进入线程池，否则抛出异常</param>
		/// <returns>是否成功添加</returns>
		public static bool QueueUserAction(Action task, int sleep = 0, bool force = false)
		{
			return FiberTaskPool.Value.Set(new ActionTask(FiberTaskPool.Value, task), sleep, force);
		}

		/// <summary>
		/// 添加后台任务
		/// </summary>
		/// <param name="task">后台任务</param>
		/// <param name="data">任务参数</param>
		/// <param name="sleep">休眠毫秒数</param>
		/// <param name="force">强制进入线程池，否则抛出异常</param>
		/// <returns>是否成功添加</returns>
		public static bool QueueUserWorkItem(Action<object> task, object data, int sleep = 0, bool force = false)
		{
			return FiberTaskPool.Value.Set(new ActionWork<object>(FiberTaskPool.Value, task, data), sleep, force);
		}
		/// <summary>
		/// 添加后台任务
		/// </summary>
		/// <param name="task">后台任务</param>
		/// <param name="data">任务参数</param>
		/// <param name="sleep">休眠毫秒数</param>
		/// <param name="force">强制进入线程池，否则抛出异常</param>
		/// <returns>是否成功添加</returns>
		public static bool QueueUserAction(Action<object> task, object data, int sleep = 0, bool force = false)
		{
			return FiberTaskPool.Value.Set(new ActionWork<object>(FiberTaskPool.Value, task, data), sleep, force);
		}

		/// <summary>
		/// 添加后台任务
		/// </summary>
		/// <param name="task">后台任务</param>
		/// <param name="data">任务参数</param>
		/// <param name="sleep">休眠毫秒数</param>
		/// <param name="force">强制进入线程池，否则抛出异常</param>
		/// <returns>是否成功添加</returns>
		public static bool QueueUserWorkItem<T>(Action<T> task, T data, int sleep = 0, bool force = false)
		{
			return FiberTaskPool.Value.Set(new ActionWork<T>(FiberTaskPool.Value, task, data), sleep, force);
		}
		/// <summary>
		/// 添加后台任务
		/// </summary>
		/// <param name="task">后台任务</param>
		/// <param name="data">任务参数</param>
		/// <param name="sleep">休眠毫秒数</param>
		/// <param name="force">强制进入线程池，否则抛出异常</param>
		/// <returns>是否成功添加</returns>
		public static bool QueueUserAction<T>(Action<T> task, T data, int sleep = 0, bool force = false)
		{
			return FiberTaskPool.Value.Set(new ActionWork<T>(FiberTaskPool.Value, task, data), sleep, force);
		}

		/// <summary>
		/// 添加后台任务
		/// </summary>
		/// <param name="task">后台任务</param>
		/// <param name="data">任务参数</param>
		/// <param name="sleep">休眠毫秒数</param>
		/// <param name="force">强制进入线程池，否则抛出异常</param>
		/// <returns>是否成功添加</returns>
		public static bool QueueUserWorkItem<T>(Func<T, IEnumerable> task, T data, int sleep = 0, bool force = false)
		{
			return FiberTaskPool.Value.Set(new ParameterizedWork<T>(FiberTaskPool.Value, task, data), sleep, force);
		}
		/// <summary>
		/// 添加后台任务
		/// </summary>
		/// <param name="task">后台任务</param>
		/// <param name="data">任务参数</param>
		/// <param name="sleep">休眠毫秒数</param>
		/// <param name="force">强制进入线程池，否则抛出异常</param>
		/// <returns>是否成功添加</returns>
		public static bool QueueUserFunction<T>(Func<T, IEnumerable> task, T data, int sleep = 0, bool force = false)
		{
			return FiberTaskPool.Value.Set(new ParameterizedWork<T>(FiberTaskPool.Value, task, data), sleep, force);
		}

		/// <summary>
		/// 添加后台任务
		/// </summary>
		/// <param name="task">后台任务</param>
		/// <param name="data">任务参数</param>
		/// <param name="sleep">休眠毫秒数</param>
		/// <param name="force">强制进入线程池，否则抛出异常</param>
		/// <returns>是否成功添加</returns>
		public static bool QueueUserWorkItem(AsyncCallback task, IAsyncResult data, int sleep = 0, bool force = false)
		{
			return FiberTaskPool.Value.Set(new AsyncCallbackTask(FiberTaskPool.Value, task, data), sleep, force);
		}
		/// <summary>
		/// 添加后台任务
		/// </summary>
		/// <param name="task">后台任务</param>
		/// <param name="data">任务参数</param>
		/// <param name="sleep">休眠毫秒数</param>
		/// <param name="force">强制进入线程池，否则抛出异常</param>
		/// <returns>是否成功添加</returns>
		public static bool QueueUserAsyncCallback(AsyncCallback task, IAsyncResult data, int sleep = 0, bool force = false)
		{
			return FiberTaskPool.Value.Set(new AsyncCallbackTask(FiberTaskPool.Value, task, data), sleep, force);
		}

		/// <summary>
		/// 添加后台任务
		/// </summary>
		/// <param name="task">后台任务</param>
		/// <param name="data">任务参数</param>
		/// <param name="sleep">休眠毫秒数</param>
		/// <param name="force">强制进入线程池，否则抛出异常</param>
		/// <returns>是否成功添加</returns>
		public static bool QueueUserWorkItem(WaitCallback task, object data, int sleep = 0, bool force = false)
		{
			return FiberTaskPool.Value.Set(new WaitCallbackTask(FiberTaskPool.Value, task, data), sleep, force);
		}
		/// <summary>
		/// 添加后台任务
		/// </summary>
		/// <param name="task">后台任务</param>
		/// <param name="data">任务参数</param>
		/// <param name="sleep">休眠毫秒数</param>
		/// <param name="force">强制进入线程池，否则抛出异常</param>
		/// <returns>是否成功添加</returns>
		public static bool QueueUserWaitCallback(WaitCallback task, object data, int sleep = 0, bool force = false)
		{
			return FiberTaskPool.Value.Set(new WaitCallbackTask(FiberTaskPool.Value, task, data), sleep, force);
		}

		/// <summary>
		/// 添加后台任务
		/// </summary>
		/// <param name="task">后台任务</param>
		/// <param name="data">任务参数</param>
		/// <param name="sleep">休眠毫秒数</param>
		/// <param name="force">强制进入线程池，否则抛出异常</param>
		/// <returns>是否成功添加</returns>
		public static bool QueueUserWorkItem(FiberStart task, object data, int sleep = 0, bool force = false)
		{
			return FiberTaskPool.Value.Set(new FiberStartWork(FiberTaskPool.Value, task, data), sleep, force);
		}
		/// <summary>
		/// 添加后台任务
		/// </summary>
		/// <param name="task">后台任务</param>
		/// <param name="data">任务参数</param>
		/// <param name="sleep">休眠毫秒数</param>
		/// <param name="force">强制进入线程池，否则抛出异常</param>
		/// <returns>是否成功添加</returns>
		public static bool QueueUserFiberStart(FiberStart task, object data, int sleep = 0, bool force = false)
		{
			return FiberTaskPool.Value.Set(new FiberStartWork(FiberTaskPool.Value, task, data), sleep, force);
		}

		/// <summary>
		/// 取当前线程数
		/// </summary>
		/// <param name="i">大于零为当前线程数，否则为活跃线程数</param>
		/// <returns>当前线程数</returns>
		public static int GetPoolThreads(int i)
		{
			if (i > 0)
				return FiberTaskPool.Value.CurrentThreads;

			return FiberTaskPool.Value.EnterThreads;
		}

		/// <summary>
		/// 设置最大线程数。
		/// </summary>
		/// <param name="max">设置最大线程数，小于等于零则为获取当前设置。</param>
		/// <returns>当前设置。</returns>
		public static int SetPoolThreads(int max)
		{
			if (max != 0)
				FiberTaskPool.Value.MaxThreads = max;
			return FiberTaskPool.Value.MaxThreads;
		}

		/// <summary>
		/// 设置计划杀死长时间任务的超时秒数
		/// </summary>
		/// <param name="timeout">最长执行秒数，小于等于零则为获取当前设置。</param>
		/// <returns>当前设置。</returns>
		public static int SetKillTimeout(int timeout)
		{
			if (timeout > 0)
				FiberTaskPool.Value.TimeoutKill = timeout;
			return FiberTaskPool.Value.TimeoutKill;
		}

		/// <summary>
		/// 仅供 <see cref="Tracker"/> 调用
		/// </summary>
		/// <returns>跟踪状态</returns>
		internal static string GetPoolTrace(string command)
		{
			return FiberTaskPool.Value.GetPoolTrace(command);
		}

		/// <summary>
		/// 判断是否为线程池线程
		/// </summary>
		/// <param name="thread">目标线程，空为当前线程</param>
		/// <returns></returns>
		public static bool IsThreadPoolThread(Thread thread)
		{
			if (thread == null)
				thread = Thread.CurrentThread;
			return thread.IsThreadPoolThread;
		}

		/// <summary>
		/// 判断是否为线程池线程
		/// </summary>
		/// <returns></returns>
		public static bool IsThreadPoolThread()
		{
			return Thread.CurrentThread.IsThreadPoolThread;
		}

		#endregion

		/// <summary>
		/// 与关键 Lock 功能相同，必须将锁定代码 try 起来并在 finally 中 <see cref="SyncUnlock"/> 解锁。
		/// </summary>
		/// <param name="syncRoot">同步锁对象</param>
		/// <param name="millisecondsTimeout">等待时间，负一表示无限等待。</param>
		/// <param name="ignoreError">忽略错误</param>
		/// <returns>永远返回 True</returns>
		public static bool SyncLock(object syncRoot, int millisecondsTimeout = int.MinValue, bool ignoreError = false)
		{
			if (millisecondsTimeout == -1 || millisecondsTimeout > 0)
			{
				if (Monitor.TryEnter(syncRoot, millisecondsTimeout))
					return true;
			}
			else
			{
				if (Monitor.TryEnter(syncRoot, Fiber.LockTimeout))
					return true;
			}

			if (ignoreError)
				return false;

			if (syncRoot == null)
				return Monitor.TryEnter(syncRoot);//此代码永不执行
			var x = new PickGold.Exceptions.LockTimeoutException("尝试获得对象上的锁超时");
			x.SyncRoot = syncRoot;
			throw x;
		}

		/// <summary>
		/// 取消锁
		/// </summary>
		/// <param name="syncRoot">同步锁对象</param>
		/// <param name="ignoreError">忽略错误</param>
		public static void SyncUnlock(object syncRoot, bool ignoreError = false)
		{
			if (ignoreError)
			{
				try
				{
					Monitor.Exit(syncRoot);
				}
				catch (SynchronizationLockException) { }
				return;
			}

			Monitor.Exit(syncRoot);
		}

		/// <summary>
		/// 引发锁超时异常
		/// </summary>
		/// <param name="syncRoot">同步锁对象</param>
		public static void ThrowLockTimeoutException(object syncRoot)
		{
			var x = new PickGold.Exceptions.LockTimeoutException("尝试获得对象上的锁超时");
			x.SyncRoot = syncRoot;
			try
			{
				throw x;
			}
			catch (Exception xx)
			{
				Tracker.LastError = xx;
				throw;
			}
		}

		/// <summary>
		/// 创建锁超时异常对象
		/// </summary>
		/// <param name="syncRoot">同步锁对象</param>
		/// <returns>返回锁超时异常</returns>
		public static Exception NewLockTimeoutException(object syncRoot)
		{
			var x = new PickGold.Exceptions.LockTimeoutException("尝试获得对象上的锁超时");
			x.SyncRoot = syncRoot;
			try
			{
				throw x;
			}
			catch (Exception xx)
			{
				Tracker.LastError = xx;
				return xx;
			}
		}
	}

	/// <summary>
	/// 线程休眠等待结构体
	/// </summary>
	public struct FiberSleep
	{
		/// <summary>
		/// 构造一个线程休眠等待结构
		/// </summary>
		/// <param name="sleep">休眠毫秒数，非精确唤醒时间，按实际唤醒时间计</param>
		public FiberSleep(int sleep)
		{
			this.Ticks = DateTime.Now.AddMilliseconds(sleep).Ticks;
		}

		/// <summary>
		/// 构造一个线程休眠等待结构
		/// </summary>
		/// <param name="sleep">休眠时间，非精确唤醒时间，按实际唤醒时间计</param>
		public FiberSleep(TimeSpan sleep)
		{
			this.Ticks = DateTime.Now.Add(sleep).Ticks;
		}

		/// <summary>
		/// 构造一个线程休眠等待结构
		/// </summary>
		/// <param name="wake">唤醒时间，非精确唤醒时间，按实际唤醒时间计</param>
		public FiberSleep(DateTime wake)
		{
			this.Ticks = wake.Ticks;
		}

		/// <summary>
		/// 唤醒时间嘀嗒数
		/// </summary>
		public long Ticks;
	}

	/// <summary>
	/// 纤程任务，可返回空，否则枚举的每次返回都将会将队列重新排队到队列末端以延迟执行，如果返回 <see cref="FiberSleep"/> 则表示等待指定时间后再尝试执行。
	/// </summary>
	/// <param name="data">参数</param>
	/// <returns>纤程分段处理标记枚举，无返回时纤程任务结束</returns>
	public delegate IEnumerable FiberStart(object data);
}
